import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
from glob import glob
import xlwings
from sklearn import linear_model
import matplotlib.pyplot as plt
import plotly.express as px
import numpy as np
import seaborn as sns
Ce projet à pour objet l'étude des données du Vendée Globe 2020, course de voilier en solitaire autour du monde. Nous allons pour cela nous appuyer sur des mesures effectuées sur les différents voiliers plusieurs fois par jours. Pour des raisons pratiques nous étudierons ces données jusqu'à l'arrivée du 1er voilier.
# extraction des données
vg = "https://www.vendeeglobe.org/fr/classement"
""""def get_filenames(url):
files = requests.get(url)
files = files.content.decode('utf-8')
soup = BeautifulSoup(files)
categorie =soup.find_all("option")
filename = []
for cat in categorie:
cat = cat.attrs["value"]
if cat != '':
filename.append(cat)
for f in filename :
lien = "https://www.vendeeglobe.org/download-race-data/vendeeglobe_"+f+".xlsx"
download = requests.get(lien)
open(f'Data/data_{f}.xlsx', 'wb').write(download.content)"""
'"def get_filenames(url):\n files = requests.get(url)\n files = files.content.decode(\'utf-8\')\n soup = BeautifulSoup(files)\n categorie =soup.find_all("option")\n filename = []\n for cat in categorie:\n cat = cat.attrs["value"]\n if cat != \'\':\n filename.append(cat)\n for f in filename :\n lien = "https://www.vendeeglobe.org/download-race-data/vendeeglobe_"+f+".xlsx"\n download = requests.get(lien)\n open(f\'Data/data_{f}.xlsx\', \'wb\').write(download.content)'
# fonction qui ouvre et réenregistre les fichiers pour éviter un bug de lecture.
"""def xlsx_broken(file):
excel_app = xlwings.App(visible=False)
excel_book = excel_app.books.open(file)
excel_book.save()
excel_book.close()
excel_app.quit()
return"""
'def xlsx_broken(file):\n excel_app = xlwings.App(visible=False)\n excel_book = excel_app.books.open(file)\n excel_book.save()\n excel_book.close()\n excel_app.quit()\n return'
"""stock_files = sorted(glob('Data/data_*.xlsx'))
for file in stock_files :
xlsx_broken(file)"""
"stock_files = sorted(glob('Data/data_*.xlsx'))\n\nfor file in stock_files :\n xlsx_broken(file)"
Au final, nous avons pu extraire 482 fichiers similaires dans leurs formats allant du 8 novembre 2020 au 27 janvier 2021.
#fonction de conversion de la latitude-longitude (source : https://en.proft.me/2015/09/20/converting-latitude-and-longitude-decimal-values-p/))
def dms2dd(degrees, minutes, seconds, direction):
dd = float(degrees) + float(minutes)/60 + float(seconds)/(60*60);
if direction == 'S' or direction == 'W':
dd *= -1
return dd;
def parse_dms(dms):
parts = re.split('[^\d\w]+', dms)
conv = dms2dd(parts[0], parts[1], parts[2], parts[3])
return (conv)
# Data cleaning
stock_files = sorted(glob('Data/*.xlsx'))
df = pd.DataFrame()
for file in stock_files :
d = pd.read_excel(file, header =4)
del d['Unnamed: 0']
d = d.rename(columns = {'Unnamed: 1' :'Rang',
'Unnamed: 2':'Nat. / Voile',
'Unnamed: 3':'Skipper / Bateau',
'Heure FR\nHour FR':'Heure FR',
'Latitude\nLatitude':'Latitude',
'Longitude\nLongitude':'Longitude',
'Cap\nHeading':'Cap Depuis 30 minutes(en degrés)',
'Vitesse\nSpeed':'Vitesse Depuis 30 minutes(en kts)',
'VMG\nVMG':'VMG Depuis 30 minutes(en kts)',
'Distance\nDistance':'Distance Depuis 30 minutes (en nm)',
'Cap\nHeading.1':'Cap Depuis le dernier classement(en degrés)',
'Vitesse\nSpeed.1':'Vitesse Depuis le dernier classement(en kts)',
'VMG\nVMG.1':'VMG Depuis le dernier classement(en kts)',
'Distance\nDistance.1':'Distance Depuis le dernier classement (en nm)',
'Cap\nHeading.2':'Cap Depuis 24 heures(en degrés)',
'Vitesse\nSpeed.2':'Vitesse Depuis 24 heures(en kts)',
'VMG\nVMG.2':'VMG Depuis 24 heures(en kts)',
'Distance\nDistance.2':'Distance Depuis 24 heures (en nm)',
'Unnamed: 19':'DTF (en nm)',
'Unnamed: 20':'DTL (en nm)'})
d = d.dropna()
#spliter les colonnes contenant des données doubles
d[['Nationalité', 'Numéro de voile']] = d['Nat. / Voile'].str.split(' ', 1, expand=True)
d[['Skipper', 'Bateau']] = d['Skipper / Bateau'].str.split('\n', 1, expand=True)
del d['Nat. / Voile']
del d['Skipper / Bateau']
# retirer les unités et les caractères indésirable
d["Cap Depuis 30 minutes(en degrés)"] = d["Cap Depuis 30 minutes(en degrés)"].str.replace('°','')
d["Cap Depuis le dernier classement(en degrés)"] = d["Cap Depuis le dernier classement(en degrés)"].str.replace('°','')
d["Cap Depuis 24 heures(en degrés)"] = d["Cap Depuis 24 heures(en degrés)"].str.replace('°','')
d["Heure FR"] = d["Heure FR"].str.replace('FR','')
d = d.replace(to_replace=' kts',value='',regex=True)
d = d.replace(to_replace=' nm',value='',regex=True)
d = d.replace(to_replace='\n',value='',regex=True)
#ajout de la colonne "date" qui comprend les dates de relevés à partir des noms des fichiers
date = f'{file[11:13]}{file[9:11]}{file[5:9]}{file[14:16]}'
d.insert(0,"Date du relevé",date,True)
d['Date du relevé'] = pd.to_datetime(d['Date du relevé'], format='%d%m%Y%H')
#changer le type des certaines colonnes en valeurs numériques
d.iloc[:,5:-5] = d.iloc[:,5:-5].apply(pd.to_numeric, downcast='float', errors = 'coerce')
d['Numéro de voile'] = d['Numéro de voile'].apply(pd.to_numeric, downcast='integer', errors = 'coerce')
d['Rang'] = d['Rang'].apply(pd.to_numeric, downcast='integer', errors = 'coerce')
# conversion latitude longitude (source : https://en.proft.me/2015/09/20/converting-latitude-and-longitude-decimal-values-p/)
d["Latitude"]=d["Latitude"].astype('string')
d["Longitude"]=d["Longitude"].astype('string')
d["Longitude"].dtype
d["Latitude_2"] = d["Latitude"].apply(parse_dms)
d["Longitude_2"] = d["Longitude"].apply(parse_dms)
del d["Longitude"]
del d["Latitude"]
#changer le type des certaines colonnes en string
d[["Skipper","Bateau","Nationalité"]] = d[["Skipper","Bateau","Nationalité"]].convert_dtypes()
df=df.append(d)
df.head(5)
| Date du relevé | Rang | Heure FR | Cap Depuis 30 minutes(en degrés) | Vitesse Depuis 30 minutes(en kts) | VMG Depuis 30 minutes(en kts) | Distance Depuis 30 minutes (en nm) | Cap Depuis le dernier classement(en degrés) | Vitesse Depuis le dernier classement(en kts) | VMG Depuis le dernier classement(en kts) | ... | VMG Depuis 24 heures(en kts) | Distance Depuis 24 heures (en nm) | DTF (en nm) | DTL (en nm) | Nationalité | Numéro de voile | Skipper | Bateau | Latitude_2 | Longitude_2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2020-11-08 14:00:00 | 1 | 15:30 | 241.0 | 17.700001 | 17.5 | 0.3 | 357.0 | 0.0 | 0.0 | ... | 0.3 | 6.1 | 24293.900391 | 0.0 | FRA | 18 | Louis Burton | Bureau Vallée 2 | 46.412778 | -1.846667 |
| 1 | 2020-11-08 14:00:00 | 2 | 15:31 1min | 241.0 | 11.100000 | 10.9 | 0.4 | 357.0 | 0.0 | 0.0 | ... | 0.2 | 6.0 | 24294.199219 | 0.4 | MON | 10 | Boris Herrmann | Seaexplorer - Yacht Club De Monaco | 46.409444 | -1.839444 |
| 2 | 2020-11-08 14:00:00 | 3 | 15:30 | 244.0 | 15.500000 | 15.5 | 0.5 | 357.0 | 0.0 | 0.0 | ... | 0.2 | 5.5 | 24294.300781 | 0.5 | FRA | 8 | Jérémie Beyou | Charal | 46.425278 | -1.844167 |
| 3 | 2020-11-08 14:00:00 | 4 | 15:30 | 244.0 | 13.200000 | 13.1 | 0.7 | 357.0 | 0.0 | 0.0 | ... | 0.2 | 5.6 | 24294.500000 | 0.6 | FRA | 59 | Thomas Ruyant | LinkedOut | 46.419722 | -1.835556 |
| 4 | 2020-11-08 14:00:00 | 5 | 15:30 | 246.0 | 10.900000 | 10.9 | 0.2 | 357.0 | 0.0 | 0.0 | ... | 0.7 | 5.8 | 24294.500000 | 0.6 | FRA | 53 | Maxime Sorel | V And B Mayenne | 46.416389 | -1.832222 |
5 rows × 23 columns
df.to_excel("Classement.xlsx")
pd.read_excel("Classement.xlsx")
| Unnamed: 0 | Date du relevé | Rang | Heure FR | Cap Depuis 30 minutes(en degrés) | Vitesse Depuis 30 minutes(en kts) | VMG Depuis 30 minutes(en kts) | Distance Depuis 30 minutes (en nm) | Cap Depuis le dernier classement(en degrés) | Vitesse Depuis le dernier classement(en kts) | ... | VMG Depuis 24 heures(en kts) | Distance Depuis 24 heures (en nm) | DTF (en nm) | DTL (en nm) | Nationalité | Numéro de voile | Skipper | Bateau | Latitude_2 | Longitude_2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 2020-11-08 14:00:00 | 1 | 15:30 | 241 | 17.700001 | 17.5 | 0.3 | 357 | 0.0 | ... | 0.3 | 6.100000 | 24293.900391 | 0.0 | FRA | 18 | Louis Burton | Bureau Vallée 2 | 46.412778 | -1.846667 |
| 1 | 1 | 2020-11-08 14:00:00 | 2 | 15:31 1min | 241 | 11.100000 | 10.9 | 0.4 | 357 | 0.0 | ... | 0.2 | 6.000000 | 24294.199219 | 0.4 | MON | 10 | Boris Herrmann | Seaexplorer - Yacht Club De Monaco | 46.409444 | -1.839444 |
| 2 | 2 | 2020-11-08 14:00:00 | 3 | 15:30 | 244 | 15.500000 | 15.5 | 0.5 | 357 | 0.0 | ... | 0.2 | 5.500000 | 24294.300781 | 0.5 | FRA | 8 | Jérémie Beyou | Charal | 46.425278 | -1.844167 |
| 3 | 3 | 2020-11-08 14:00:00 | 4 | 15:30 | 244 | 13.200000 | 13.1 | 0.7 | 357 | 0.0 | ... | 0.2 | 5.600000 | 24294.500000 | 0.6 | FRA | 59 | Thomas Ruyant | LinkedOut | 46.419722 | -1.835556 |
| 4 | 4 | 2020-11-08 14:00:00 | 5 | 15:30 | 246 | 10.900000 | 10.9 | 0.2 | 357 | 0.0 | ... | 0.7 | 5.800000 | 24294.500000 | 0.6 | FRA | 53 | Maxime Sorel | V And B Mayenne | 46.416389 | -1.832222 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 13698 | 20 | 2021-01-27 14:00:00 | 21 | 14:30 | 347 | 8.900000 | 7.9 | 4.4 | 355 | 13.7 | ... | 12.0 | 310.399994 | 4521.700195 | 4441.2 | FRA | 71 | Manuel Cousin | Groupe Sétin | -24.011667 | -26.806389 |
| 13699 | 21 | 2021-01-27 14:00:00 | 22 | 14:30 | 348 | 10.900000 | 9.9 | 5.4 | 349 | 11.8 | ... | 9.8 | 252.000000 | 4639.100098 | 4558.6 | FRA | 50 | Miranda Merron | Campagne de France | -26.187778 | -26.041944 |
| 13700 | 22 | 2021-01-27 14:00:00 | 23 | 14:30 | 7 | 11.000000 | 10.9 | 5.5 | 1 | 10.1 | ... | 7.9 | 230.399994 | 4674.600098 | 4594.1 | FRA | 83 | Clément Giraud | Compagnie du lit - Jiliti | -26.001944 | -29.507500 |
| 13701 | 23 | 2021-01-27 14:00:00 | 24 | 14:30 | 25 | 10.100000 | 10.0 | 5.0 | 23 | 9.1 | ... | 11.4 | 273.700012 | 6341.500000 | 6260.9 | FRA | 72 | Alexia Barrier | TSE - 4myplanet | -48.151389 | -53.862500 |
| 13702 | 24 | 2021-01-27 14:00:00 | 25 | 14:30 | 44 | 9.400000 | 9.2 | 4.7 | 38 | 10.8 | ... | 11.5 | 275.799988 | 6376.700195 | 6296.1 | FIN | 222 | Ari Huusela | Stark | -49.383611 | -52.491389 |
13703 rows × 24 columns
Maintenant que les données sont extraites et exploitables au sein d'un dataset, il convient de les exploiter. Pour cela on va s'interesser à 2 aspects du Vendée Globe. L'impact de la vitesse sur le classement et les abandons.
df.groupby(['Skipper', 'Numéro de voile'])['Distance Depuis 24 heures (en nm)'].mean().sort_values(ascending=False)
Skipper Numéro de voile Charlie Dalin 79 331.893982 Thomas Ruyant 59 330.590240 Louis Burton 18 330.461426 Boris Herrmann 10 328.065338 Kevin Escoffier 85 327.411682 Yannick Bestaven 17 327.220337 Giancarlo Pedote 34 324.185059 Benjamin Dutreux 9 320.427399 Damien Seguin 1000 320.201660 Jean Le Cam 1 319.442322 Isabelle Joschke 27 318.225281 Armel Tripon 2 316.875946 Sébastien Simon 4 314.924683 Maxime Sorel 53 312.527588 Jérémie Beyou 8 307.926361 Samantha Davies 109 306.887115 Alex Thomson 99 304.442963 Clarisse Cremer 30 304.438782 Romain Attanasio 49 292.501648 Arnaud Boissieres 14 285.906677 Kojiro Shiraishi 11 284.768890 Stéphane Le Diraison 92 284.612244 Alan Roura 7 282.281128 Didac Costa 33 279.685272 Pip Hare 777 276.386719 Manuel Cousin 71 273.325928 Nicolas Troussel 6 269.395996 Miranda Merron 50 264.960388 Clément Giraud 83 264.628021 Ari Huusela 222 248.431534 Alexia Barrier 72 242.834229 Fabrice Amedeo 56 236.703506 Sébastien Destremau 69 212.909348 Name: Distance Depuis 24 heures (en nm), dtype: float32
Sans suprise, on s'apercoit que les 3 skippers sur le podium font partie des plus rapides (Bien que le cas de Yannick Bestaven soit particulier).
df['Rang'] = df['Rang'].astype(str).astype(int)
name = df["Skipper"].unique()
y=[]
x=[]
for names in name :
moy_1= df[df['Skipper']== names]["VMG Depuis le dernier classement(en kts)"].mean()
moy_2= df[df['Skipper']== names]["Rang"].mean()
y.append(moy_1)
x.append(moy_2)
X = np.array(x)
Y = np.array(y)
linmod = linear_model.LinearRegression()
linmod.fit(X.reshape(-1, 1), Y)
print('En utilisant ''sklearn.linear_model'', les paramètres estimés sont:')
print('b0 = {:.4f},'.format(linmod.intercept_))
print('b1 = {:.4f}.'.format(linmod.coef_[0]))
print('\nCoefficient de détermination R^2 = {:.4f}.'
.format(linmod.score(X.reshape(-1, 1), Y)))
X0 = np.array([[15.9, ]])
Y0 = linmod.predict(X0)
print(f'Pour une VMG ={X0}, le skipper devrait arriver classé {Y0}.')
Y_pred = linmod.predict(X.reshape(-1, 1))
plt.figure()
plt.scatter(X, Y, label='Classement en foncion de la vitesse moyenne')
plt.scatter(X0, Y0, label="Prediction pour l'observation X0")
plt.plot(X, Y_pred, c='k', label='Regression line')
plt.title('Rang par rapport à la VMG')
plt.xlabel('VMG')
plt.ylabel('Rang')
plt.legend()
plt.show()
En utilisant sklearn.linear_model, les paramètres estimés sont: b0 = 13.2149, b1 = -0.1329. Coefficient de détermination R^2 = 0.6564. Pour une VMG =[[15.9]], le skipper devrait arriver classé [11.10205846].
En tracant une droite de regression, on voit clairement qu'une augmentation de la vitesse moyenne à pour effet direct d'augmenter son classement. Cependant ce n'est pas le seul determinant car le coefficient de determination n'est que de 0,65. A partir de cette droite de regression on peut se permettre de faire une estimation du rang en fonction de la vitesse moyenne (ici le point orange).
Interessons nous maintenant aux abandons. Chaque année de nombreux abandons son constatés tout au long de la compétition.
# Calcul du nombre de Skipper restant au fur et à mesure de la course
x = df["Date du relevé"].unique()
y = df["Date du relevé"].value_counts()
plt.figure()
plt.bar(x, y, width = 0.1 )
plt.title('Nombre de Skipper au fur et a mesure de la course')
plt.xlabel('Evolution dans le temps')
plt.ylabel('Nombre de skippers en course')
plt.show()
Un rapide regard sur le nombre de participants montre aussi qu'il y'a eu plusieurs abandons au cours de la course, passant de 33 participants à 24 à la fin. Mais observons ces 9 abandons de plus près.
# On etablit la liste des 9 skippers qui ont abandonné par ordre d'abandon
df['Skipper'].value_counts(ascending=True).to_frame()[:9]
| Skipper | |
|---|---|
| Nicolas Troussel | 50 |
| Kevin Escoffier | 137 |
| Alex Thomson | 156 |
| Sébastien Simon | 158 |
| Samantha Davies | 163 |
| Fabrice Amedeo | 200 |
| Isabelle Joschke | 376 |
| Sébastien Destremau | 417 |
| Arnaud Boissieres | 479 |
On voit sur ce tableau que certains skippers ont abandonné dès le début de la course comme Nicolas Troussel alors que d'autres ont abandonnés en fin de course comme Arnaud Boissières.
# Représentation de toutes les tragectoires prises par des skippers
fig1 = px.line_geo( df,
lat = df["Latitude_2"],
lon = df["Longitude_2"],
color="Skipper",
projection='natural earth')
fig1.show()
Sur cette carte interactive, nous pouvons observer le trajets des 9 skippers qui ont abandonnés (en selectionnant les skippers sur la droite) et voir le point géographique exacte pour chacun des abandons. Le plus souvent au passage d'un cap (au sud de l'Afrique ou de l'Amerique du sud)
Interessons nous maintenant aux données techniques sur les bateaux.
#Extractions des données techniques sur les voiliers
r = requests.get('https://www.vendeeglobe.org/fr/glossaire')
content = r.content.decode('utf-8')
soup = BeautifulSoup(r.content)
soup
nom_bateau = soup.find_all('h3', attrs={'class':'boats-list__boat-name'})
spec_bateau = soup.find('ul', attrs={'class':'boats-list__popup-specs-list'}).find_all('li')
specificite = []
for d in soup.find_all('div', attrs={'class': 'boats-list__popup-infos'}):
name = d.find('h3', attrs={'class':'boats-list__popup-title'}).text
team = {'Team': name}
for spec in d.find('ul', attrs={'class':'boats-list__popup-specs-list'}).find_all('li') :
spec = spec.text.split(":")
team[spec[0]] = spec[1]
specificite.append(team)
new_df = pd.DataFrame(specificite)
new_df.columns = new_df.columns.str.strip()
# On renomme les colonnes
new_df = new_df.rename(columns = {'Longueur':'Longueur (en m)',
'Largeur':'Largeur (en m)',
"Tirant d'eau":"Tirant d'eau (en m)",
'Déplacement (poids)':'Déplacement (poids en tonne)',
'Hauteur mât':'Hauteur mât (en m)',
'Surface de voiles au près':'Surface de voiles au près (en m²)',
'Surface de voiles au portant':'Surface de voiles au portant (en m²)'})
# retirer la colonne "Anciens noms du bateau" qui contient trop de Nan :
del new_df["Anciens noms du bateau"]
# Suppression des unités dans les colonnes et conversion de certaines colonnes en float:
new_df = new_df.replace(to_replace='m2',value='',regex=True)
new_df["Déplacement (poids en tonne)"] = new_df["Déplacement (poids en tonne)"].replace(to_replace='tonnes',value='',regex=True)
new_df["Déplacement (poids en tonne)"] = new_df["Déplacement (poids en tonne)"].replace(to_replace='t',value='',regex=True)
new_df = new_df.replace(to_replace=',',value='.',regex=True)
col = ["Longueur (en m)","Largeur (en m)","Tirant d'eau (en m)","Hauteur mât (en m)"]
for colonnes in col :
new_df[colonnes] = new_df[colonnes].str.replace('m','')
new_df[colonnes] = new_df[colonnes].apply(float)
# on modifie les données erronnées sur la voile :
new_df['Numéro de voile'] = new_df['Numéro de voile'].str.strip(" FRA ESP FIN TA UI JPN GBR")
new_df.loc[new_df['Team'] == "LinkedOut",'Numéro de voile'] = 59
new_df.loc[new_df['Team'] == "MEDALLIA",'Numéro de voile'] = 777
new_df.loc[new_df['Team'] == "SEAEXPLORER - YACHT CLUB DE MONACO",'Numéro de voile'] = 10
new_df['Numéro de voile'] = new_df['Numéro de voile'].apply(pd.to_numeric, downcast='integer', errors = 'coerce')
#Convertion de certaines valeurs en valeurs numériques
new_df.iloc[:,-2:] = new_df.iloc[:,-2:].apply(pd.to_numeric, downcast='integer', errors = 'coerce')
On fusionne ensuite les 2 tableaux en 1 à partir de la colonne 'Numéro de voile' présente dans les 2 tableaux
df_full = pd.merge(df, new_df, on="Numéro de voile",how="left")
df_full
| Date du relevé | Rang | Heure FR | Cap Depuis 30 minutes(en degrés) | Vitesse Depuis 30 minutes(en kts) | VMG Depuis 30 minutes(en kts) | Distance Depuis 30 minutes (en nm) | Cap Depuis le dernier classement(en degrés) | Vitesse Depuis le dernier classement(en kts) | VMG Depuis le dernier classement(en kts) | ... | Date de lancement | Longueur (en m) | Largeur (en m) | Tirant d'eau (en m) | Déplacement (poids en tonne) | Nombre de dérives | Hauteur mât (en m) | Voile quille | Surface de voiles au près (en m²) | Surface de voiles au portant (en m²) | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2020-11-08 14:00:00 | 1 | 15:30 | 241.0 | 17.700001 | 17.5 | 0.3 | 357.0 | 0.0 | 0.0 | ... | 09 Juin 2015 | 18.28 | 5.80 | 4.5 | 7.6 | foils | 28.0 | acier | 300.0 | 600.0 |
| 1 | 2020-11-08 14:00:00 | 2 | 15:31 1min | 241.0 | 11.100000 | 10.9 | 0.4 | 357.0 | 0.0 | 0.0 | ... | 07 Août 2015 | 18.28 | 5.70 | 4.5 | 7.6 | foils | 29.0 | acier | 290.0 | 490.0 |
| 2 | 2020-11-08 14:00:00 | 3 | 15:30 | 244.0 | 15.500000 | 15.5 | 0.5 | 357.0 | 0.0 | 0.0 | ... | 18 Août 2018 | 18.28 | 5.85 | 4.5 | 8 | foils | 29.0 | acier | 320.0 | 600.0 |
| 3 | 2020-11-08 14:00:00 | 4 | 15:30 | 244.0 | 13.200000 | 13.1 | 0.7 | 357.0 | 0.0 | 0.0 | ... | 03 Septembre 2019 | 18.28 | 5.85 | 4.5 | 8 | foils | 29.0 | acier forgé | 350.0 | 560.0 |
| 4 | 2020-11-08 14:00:00 | 5 | 15:30 | 246.0 | 10.900000 | 10.9 | 0.2 | 357.0 | 0.0 | 0.0 | ... | 07 Septembre 2007 | 18.28 | 5.50 | 4.5 | 7.7 | 2 | 29.0 | acier | 365.0 | 700.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 13698 | 2021-01-27 14:00:00 | 21 | 14:30 | 347.0 | 8.900000 | 7.9 | 4.4 | 355.0 | 13.7 | 13.0 | ... | 02 Février 2007 | 18.28 | 5.80 | 4.5 | 9 | 2 asymétriques | 28.5 | basculante sur vérin hydraulique | 270.0 | 560.0 |
| 13699 | 2021-01-27 14:00:00 | 22 | 14:30 | 348.0 | 10.900000 | 9.9 | 5.4 | 349.0 | 11.8 | 10.8 | ... | 04 Mai 2006 | 18.28 | 5.50 | 4.5 | 8.5 | 2 | 28.0 | carbone | 330.0 | 600.0 |
| 13700 | 2021-01-27 14:00:00 | 23 | 14:30 | 7.0 | 11.000000 | 10.9 | 5.5 | 1.0 | 10.1 | 9.8 | ... | 26 Juillet 2006 | 18.28 | 5.75 | 4.5 | 8.5 | 2 | 29.0 | acier forgé | 300.0 | 620.0 |
| 13701 | 2021-01-27 14:00:00 | 24 | 14:30 | 25.0 | 10.100000 | 10.0 | 5.0 | 23.0 | 9.1 | 9.0 | ... | 01 Mars 1998 | 18.28 | 5.54 | 4.5 | 9 | 2 | 29.0 | acier | 260.0 | 580.0 |
| 13702 | 2021-01-27 14:00:00 | 25 | 14:30 | 44.0 | 9.400000 | 9.2 | 4.7 | 38.0 | 10.8 | 10.7 | ... | 06 Août 2007 | 18.28 | 5.80 | 4.5 | 8.5 | 2 | 28.0 | acier | 270.0 | 580.0 |
13703 rows × 36 columns
# Mise en place d'un barchart pour voir si il y'a un lien evident entre les surfaces de voiles et le classement
for voile in ["Surface de voiles au près (en m²)","Surface de voiles au portant (en m²)"]:
sns.barplot(x= voile, y="Rang", data=df_full, ci=None)
plt.show()
Cette courte exploration des données consiste à observer si il y a un lien entre le classement et la surface des différentes voiles. Cependant, on voit que cette caractérisque ne semble pas déterminante dans la course puisqu'aucune tendance ne ressort du graphe.
Au cours de ce projet, nous avons extrait et analyser différentes données du Vendée Globe. Il en ressort :
Il y'a eu 9 abandons au cours de la course. On voit que ces abandons arrivent souvent au niveau des caps. Les abandons sont assez réparties tout au long de la course.
Concernant les données techniques on ne peut pas determiner que la taille des voiles lors de la compétition à une incidence non significative sur le résultat de la course.
A noter cependant que les tailles de voiles sont assez similaires entre les voiliers.